wayland: Cache the discovery connection and reuse if possible
authorRob Bradford <rob@linux.intel.com>
Fri, 19 Apr 2013 12:59:58 +0000 (13:59 +0100)
committerRob Bradford <rob@linux.intel.com>
Fri, 19 Apr 2013 13:03:24 +0000 (14:03 +0100)
This will prevent us opening, closing and reopening the same display
connection in the majority of cases.

https://bugzilla.gnome.org/show_bug.cgi?id=694465

gdk/wayland/gdkdisplay-wayland.c
gdk/wayland/gdkdisplaymanager-wayland.c
gdk/wayland/gdkprivate-wayland.h

index ee42ea9c8d112fc541cdb2d136afceca740cfbd9..06bbf4922514d0d4409098018fad2a2c62af1890 100644 (file)
@@ -214,18 +214,13 @@ log_handler(const char *format, va_list args)
 }
 
 GdkDisplay *
-_gdk_wayland_display_open (const gchar *display_name)
+_gdk_wayland_display_open (struct wl_display *wl_display)
 {
-  struct wl_display *wl_display;
   GdkDisplay *display;
   GdkWaylandDisplay *display_wayland;
 
   wl_log_set_handler_client(log_handler);
 
-  wl_display = wl_display_connect(display_name);
-  if (!wl_display)
-    return NULL;
-
   display = g_object_new (GDK_TYPE_WAYLAND_DISPLAY, NULL);
   display_wayland = GDK_WAYLAND_DISPLAY (display);
 
index 902ac164b02fb1a2be719c8b111c20c06bff5bb9..f5b664c333464fda008c18c0ad0a0355758e75ac 100644 (file)
@@ -34,6 +34,10 @@ struct _GdkWaylandDisplayManager
   GSList *displays;
 
   gboolean init_failed;
+  struct {
+      struct wl_display *wl_display;
+      gchar *name;
+  } cached_display;
 };
 
 struct _GdkWaylandDisplayManagerClass
@@ -51,6 +55,7 @@ gdk_wayland_display_manager_initable_init (GInitable     *initable,
                                            GCancellable  *cancellable,
                                            GError       **error)
 {
+  GdkWaylandDisplayManager *manager = GDK_WAYLAND_DISPLAY_MANAGER (initable);
   struct wl_display *wl_display;
 
   /* Set by the compositor when launching a special client - and it gets reset
@@ -64,12 +69,12 @@ gdk_wayland_display_manager_initable_init (GInitable     *initable,
 
   if (!wl_display)
     {
-      GDK_WAYLAND_DISPLAY_MANAGER (initable)->init_failed = TRUE;
+      manager->init_failed = TRUE;
       return FALSE;
     }
 
-  wl_display_disconnect (wl_display);
-
+  manager->cached_display.name = g_strdup (gdk_get_display_arg_name ());
+  manager->cached_display.wl_display = wl_display;
   return TRUE;
 }
 
@@ -89,10 +94,35 @@ gdk_wayland_display_manager_finalize (GObject *object)
 }
 
 static GdkDisplay *
-gdk_wayland_display_manager_open_display (GdkDisplayManager *manager,
+gdk_wayland_display_manager_open_display (GdkDisplayManager *display_manager,
                                          const gchar       *name)
 {
-  return _gdk_wayland_display_open (name);
+  GdkWaylandDisplayManager *manager = GDK_WAYLAND_DISPLAY_MANAGER (display_manager);
+  struct wl_display *wl_display;
+
+  if (name == manager->cached_display.name || 
+      g_strcmp0 (name, manager->cached_display.name))
+    {
+      /* Cache hit */
+      wl_display = manager->cached_display.wl_display;
+    }
+
+  if (!wl_display)
+    {
+      /* Cache miss */
+      if (manager->cached_display.wl_display)
+        wl_display_disconnect (manager->cached_display.wl_display);
+      wl_display = wl_display_connect (name);
+    }
+
+  /* Use the cache at most once */
+  g_free (manager->cached_display.name);
+  manager->cached_display.wl_display = NULL;
+
+  if (!wl_display)
+    return NULL;
+
+  return _gdk_wayland_display_open (wl_display);
 }
 
 static void
index 02d5b6dcaf5b16a3a743af0f65ab64b3709570bf..dc7f0039ef6b945e6a2a90181fd4deefd1eabc10 100644 (file)
@@ -155,7 +155,7 @@ void     _gdk_wayland_display_queue_events (GdkDisplay *display);
 
 GdkAppLaunchContext *_gdk_wayland_display_get_app_launch_context (GdkDisplay *display);
 
-GdkDisplay *_gdk_wayland_display_open (const gchar *display_name);
+GdkDisplay *_gdk_wayland_display_open (struct wl_display *display);
 
 GdkWindow *_gdk_wayland_screen_create_root_window (GdkScreen *screen,
                                                   int width,